package com.suredy.app.index.ctrl;

import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.suredy.Constants;
import com.suredy.app.ctrl.AppBaseCtrl;
import com.suredy.app.porject.constants.ContractType;
import com.suredy.app.porject.ctrl.view.ViewRoleCtrl;
import com.suredy.app.porject.service.ContractSrv;
import com.suredy.security.model.User;
import com.suredy.security.service.UserSrv;

@Controller
public class IndexCtrl extends AppBaseCtrl {

	@Autowired
	private UserSrv userSrv;

	@Autowired
	private ContractSrv contractSrv;

	@RequestMapping(value = "index", method = RequestMethod.GET)
	public ModelAndView Index(HttpServletRequest request) {
		User user = (User) request.getSession().getAttribute(Constants.SESSION_LOGIN_USER);
		List<String> allowed = this.userSrv.getPermissions(user.getUniqueCode());
		ModelAndView view = new ModelAndView("/index");
		view.addObject("permissions", allowed);
		view.addObject("roles", new ViewRoleCtrl(this.getUser(), this.getRoleCodesFromSession()));

		return view;
	}

	@RequestMapping(value = "/user-config", method = RequestMethod.GET)
	public String userConfig(Model model) {
		String view = "app/user/pswd";

		User u = this.getUser();

		model.addAttribute("data", u);

		return view;
	}

	@RequestMapping(value = "/user-config", method = RequestMethod.POST)
	@ResponseBody
	public boolean updatePswd(String old, String pswd) {
		if (StringUtils.isBlank(old) || StringUtils.isBlank(pswd))
			return false;

		int count = this.userSrv.updateUserPswd(this.getUser().getId(), old, pswd);

		return count == 1;
	}

	@SuppressWarnings("all")
	@RequestMapping(value = "/index/countract-count", method = RequestMethod.GET)
	@ResponseBody
	public Object getContractCountOnIndexPage() {
		Date[] d = this.getDateOfContractCountOnIndexPage();

		ProjectionList pl = Projections.projectionList();
		pl.add(Property.forName("type"));
		pl.add(Property.forName("price"));
		pl.add(Property.forName("clearingPrice"));
		pl.add(Property.forName("start"));
		pl.add(Property.forName("contractStart"));

		DetachedCriteria dc = this.contractSrv.getDc(null);
		dc.setProjection(pl);
		dc.add(Restrictions.in("type", ContractType.MAIN_CONTRACT_TYPES));
		dc.add(Restrictions.or(Restrictions.isNotNull("price"), Restrictions.isNotNull("clearingPrice")));
		dc.add(Restrictions.or(Restrictions.between("start", d[0], d[1]), Restrictions.between("contractStart", d[0], d[1])));

		List<Object[]> data = (List<Object[]>) this.contractSrv.readByCriteria(dc);

		int year = new Date().getYear() + 1900;
		Map<Integer, Double[]> ret = new LinkedHashMap<Integer, Double[]>();

		for (int i = year - 1; i <= year + 1; i++) {
			ret.put(i, new Double[] {0D, 0D});
		}

		if (data != null) {
			for (Object[] c : data) {
				ContractType type = (ContractType) c[0];
				Double price = (Double) c[1];
				Double clearingPrice = (Double) c[2];
				Date start = (Date) c[3];
				Date contractStart = (Date) c[4];

				Date dt = start;
				dt = dt == null ? contractStart : dt;

				if (dt == null)
					continue;

				int y = dt.getYear() + 1900; // real year

				Double p = clearingPrice;
				if (p == null)
					p = price;

				if (p == null)
					continue;

				// merge count
				Double[] dd = ret.get(y);

				if (dd == null)
					continue;

				if (type.isCollection()) {
					// 收款
					dd[0] += p;
				} else {
					// 付款
					dd[1] += p;
				}
			}
		}

		return ret;
	}

	private Date[] getDateOfContractCountOnIndexPage() {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.MONTH, Calendar.JANUARY); // 1月
		c.set(Calendar.DAY_OF_MONTH, 1); // 1日
		c.set(Calendar.HOUR_OF_DAY, 0); // 0时
		c.set(Calendar.MINUTE, 0); // 0分
		c.set(Calendar.SECOND, 0); // 0秒
		c.set(Calendar.MILLISECOND, 0); // 0毫秒

		Date[] d = new Date[2];

		c.add(Calendar.YEAR, -1); // 上一年

		d[0] = c.getTime();

		c.add(Calendar.YEAR, 3); // 后年（不再查询范围内）

		d[1] = c.getTime();

		return d;
	}

}
